package com.platform.common.mybatis.interceptor;

import com.platform.common.mybatis.Page;
import com.platform.common.mybatis.PageUtil;
import com.platform.common.mybatis.context.ContextHolder;
import com.platform.common.util.ReflectUtil;
import org.apache.ibatis.executor.statement.PreparedStatementHandler;
import org.apache.ibatis.executor.statement.RoutingStatementHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.RowBounds;

import java.sql.Connection;
import java.util.Properties;

@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class})})
public class DiclectStatementHandlerInterceptor_back extends PageUtil implements Interceptor {

    private static String dialect; //数据库方言
    //	private static String pageSqlId = ""; //mapper.xml中需要拦截的ID(正则匹配)


    public Object intercept(Invocation invocation) throws Throwable {
        RoutingStatementHandler statement = (RoutingStatementHandler) invocation.getTarget();
        PreparedStatementHandler handler = (PreparedStatementHandler) ReflectUtil.getFieldValue(statement, "delegate");
        RowBounds rowBounds = (RowBounds) ReflectUtil.getFieldValue(handler, "rowBounds");
        Page page = ContextHolder.getPage();
        if (page != null) {
        //if (rowBounds.getLimit() > 0 && rowBounds.getLimit() < RowBounds.NO_ROW_LIMIT) {
            // MappedStatement mappedStatement = (MappedStatement)ReflectUtil.getFieldValue(handler, "mappedStatement");
            Connection conn = (Connection) invocation.getArgs()[0];
            dialect = conn.getMetaData().getDatabaseProductName().toLowerCase();
            BoundSql boundSql = statement.getBoundSql();
            String sql = boundSql.getSql();
            sql = PageUtil.getLimitString(dialect, sql, page.getCurrentResult(), page.getPageSize());
            ReflectUtil.setFieldValue(boundSql, "sql", sql);
            ContextHolder.removePage();
        }
        return invocation.proceed();
    }

    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    public void setProperties(Properties properties) {
    }

}
